<?php
/**
 * Node.php
 * Created by PhpStorm.
 * User: 江小波
 * Date: 2019/6/5
 * Time: 11:15
 */
namespace app\common\simple_rbac;

use app\common\RecursiveTrait;
use app\common\Singleton;
use think\Hook;

class Node
{
    use Singleton,RecursiveTrait;

    // 最后一次错误信息
    protected $error = "error";

    // 当前模块
    protected $moduleName;
    // 当前控制器
    protected $controllerName;
    // 当前方法
    protected $actionName;

    /**
     * Logic constructor.
     * @param null $connect
     */
    public function __construct()
    {
        // 请求实例
        $request = request();
        $this->moduleName = strtolower($request->module());
        $this->controllerName = strtolower($request->controller());
        $this->actionName = strtolower($request->action());
    }

    /**
     * 获取模块名称
     * @return string
     */
    public function getModuleName()
    {
        return $this->moduleName;
    }

    /**
     * 获取控制器名称
     * @return string
     */
    public function getControllerName()
    {
        return $this->controllerName;
    }

    /**
     * 获取方法名称
     * @return string
     */
    public function getActionName()
    {
        return $this->actionName;
    }

    /**
     * 获取最后一次错误信息
     * @return string
     */
    public function getError()
    {
        return $this->error;
    }

    /**
     * 获取当前访问节点ID列表
     * @return array
     * @throws \Exception
     */
    public function current()
    {
        $module = Model::getInstance()->getNode(['level'=>1,'name'=>$this->getModuleName()],'id');
        // 保存模块
        if(empty($module['id']))
        {
            $module_id = Model::getInstance()->addNode([
                'level' => 1,
                'create_ts' => time(),
                'pid' => 0,
                'tid' => 0,
                'name' => $this->getModuleName(),
                'title' => $this->getModuleName(),
                'remark' => $this->getModuleName(),
            ]);
            if(!$module_id)
            {
                // 保存节点详情错误
                Hook::listen("save_node_info_error",$module_id);
                throw new \Exception('save_node_info_error::module');
            }
            // 再重新保存树形结构
            $status = Model::getInstance()->saveNode(['id'=>$module_id],['update_ts'=>time(),'tree'=>",{$module_id},"]);
            if(!$status)
            {
                // 保存树形失败，请记录日志或者处理
                Hook::listen("save_node_tree_error",$module_id);
                throw new \Exception('save_node_tree_error::module');
            }
        }else{
            $module_id = $module['id'];
        }
        $controller = Model::getInstance()->getNode(['pid'=>$module_id,'level'=>2,'name'=>$this->getControllerName()],'id');
        // 保存控制器
        if(empty($controller['id']))
        {
            $controller_id = Model::getInstance()->addNode([
                'level' => 2,
                'create_ts' => time(),
                'pid' => $module_id,
                'tid' => $module_id,
                'name' => $this->getControllerName(),
                'title' => $this->getControllerName(),
                'remark' => $this->getControllerName(),
            ]);
            if(!$controller_id)
            {
                // 保存节点详情错误
                Hook::listen("save_node_info_error",$controller_id);
                throw new \Exception('save_node_info_error::controller');
            }
            // 再重新保存树形结构
            $status = Model::getInstance()->saveNode(['id'=>$controller_id],['update_ts'=>time(),'tree'=>",{$module_id},{$controller_id},"]);
            if(!$status)
            {
                // 保存树形失败，请记录日志或者处理
                Hook::listen("save_node_tree_error",$controller_id);
                throw new \Exception('save_node_tree_error::controller');
            }
        }else{
            $controller_id = $controller['id'];
        }
        $action = Model::getInstance()->getNode(['pid'=>$controller_id,'level'=>3,'name'=>$this->getActionName()],'id');
        // 保存方法
        if(empty($action['id']))
        {
            $action_id = Model::getInstance()->addNode([
                'level' => 3,
                'create_ts' => time(),
                'pid' => $controller_id,
                'tid' => $module_id,
                'name' => $this->getActionName(),
                'title' => $this->getActionName(),
                'remark' => $this->getActionName(),
            ]);
            if(!$action_id)
            {
                // 保存节点详情错误
                Hook::listen("save_node_info_error",$action_id);
                throw new \Exception('save_node_info_error::action');
            }
            // 再重新保存树形结构
            $status = Model::getInstance()->saveNode(['id'=>$action_id],['update_ts'=>time(),'tree'=>",{$module_id},{$controller_id},{$action_id}"]);
            if(!$status)
            {
                // 保存树形失败，请记录日志或者处理
                Hook::listen("save_node_tree_error",$action_id);
                throw new \Exception('save_node_tree_error::action');
            }
        }else{
            $action_id = $action['id'];
        }
        return [$module_id,$controller_id,$action_id];
    }
}